namespace CRM_Perf_BenchMark
{
    using System;
    using System.Collections.Generic;
    using Microsoft.VisualStudio.TestTools.WebTesting;
    using System.Net;

    /// <summary>
    ///1. Start point Homepage
    ///2. Select Tools, Advanced Find
    ///3. Select Contracts
    ///4. Contract Name contains "Random string"
    ///5. Select Find Search
    /// </summary>

    public class AdvancedFindContract : CrmWebTest
    {
        public void AdvancedFindContract_PreWebTest(object sender, PreWebTestEventArgs e)
        {
            EntityRequest er = new EntityRequest();
            er.Type = EntityNames.Users;
            er.ReturnAs = EntityNames.Users;
            er.ParentID = EntityManager.Instance.OrgId;

            System.Collections.Hashtable userProps = new System.Collections.Hashtable();
            if (e.WebTest.Context.ContainsKey("UserRole"))
            {
                userProps.Add("role", e.WebTest.Context["UserRole"]);
                er.Props = userProps;
            }

            System.Collections.Hashtable Entities = EntityManager.Instance.GetEntities(er);

            user = (CRMEntity)Entities[EntityNames.Users];

            e.WebTest.UserName = user["domainName"];
            e.WebTest.Password = user["userpassword"];
            
            crmServer = user["CrmServer"];
            tokenKey = EntityManager.Instance.ReadTokenKey(user["organizationid"]);
        }

        public void AdvancedFindContract_PostWebTest(object sender, PostWebTestEventArgs e)
        {
            EntityManager.Instance.FreeEntity(user);
        }

        public AdvancedFindContract()
        {
            WebRequest.RegisterPrefix("crm", new crmRequestFactory());
            this.Proxy = null;            
            PreWebTest += new EventHandler<PreWebTestEventArgs>(AdvancedFindContract_PreWebTest);
            PostWebTest += new EventHandler<PostWebTestEventArgs>(AdvancedFindContract_PostWebTest);
        }

        public override IEnumerator<WebTestRequest> GetRequestEnumerator()
        {

            this.BeginTransaction("AdvancedFindContract");            

            AdvancedFind_AdvFind_aspx AdvFind_aspx = new AdvancedFind_AdvFind_aspx(user);
            AdvFind_aspx.EntityCode = 9100;
            AdvFind_aspx.QueryId = new Guid("{687635FF-5117-40C8-9A04-3467307134E1}");
            AdvFind_aspx.ViewType = 1039;
            yield return (AdvFind_aspx);

            AdvancedFind.AdvancedFind af = new AdvancedFind.AdvancedFind();
            WebTestRequest wtr = null;

            try { af.GetQueryList("report", 0, true, true, false); }
            catch (crmException x)
            {
                wtr = (CrmRequest)x.wtr;
                wtr.Url = Utils.ReplaceServerName(wtr.Url, user);
            }
            yield return (wtr);

            try { af.GetSystemQuery("{687635FF-5117-40C8-9A04-3467307134E1}"); }
            catch (crmException x)
            {
                wtr = (CrmRequest)x.wtr;
                wtr.Url = Utils.ReplaceServerName(wtr.Url, user);
            }
            yield return (wtr);

            try { af.GetDefaultAdvancedFindView("report", false); }
            catch (crmException x)
            {
                wtr = (CrmRequest)x.wtr;
                wtr.Url = Utils.ReplaceServerName(wtr.Url, user);
            }
            yield return (wtr);

            try { af.GetLinkedEntityList("report"); }
            catch (crmException x)
            {
                wtr = (CrmRequest)x.wtr;
                wtr.Url = Utils.ReplaceServerName(wtr.Url, user);

                string urlPath = wtr.Url.Remove(0, crmServer.Length);
                urlPath = urlPath.Remove(0, user["organizationName"].Length + 1);

                rpcInfo = Utils.GenerateWRPCToken(urlPath, user, tokenKey);

                headerItem = new WebTestRequestHeader();
                headerItem.Name = "crmwrpctokentimestamp";
                headerItem.Value = rpcInfo.timeStamp.ToString();
                wtr.Headers.Add(headerItem);
                headerItem = new WebTestRequestHeader();
                headerItem.Name = "crmwrpctoken";
                headerItem.Value = rpcInfo.token;
                wtr.Headers.Add(headerItem);
                wtr.Method = "Post";
            }
            yield return (wtr);

            try { af.GetEntityFieldList("report"); }
            catch (crmException x)
            {
                wtr = (CrmRequest)x.wtr;
                wtr.Url = Utils.ReplaceServerName(wtr.Url, user);

                string urlPath = wtr.Url.Remove(0, crmServer.Length);
                urlPath = urlPath.Remove(0, user["organizationName"].Length + 1);

                rpcInfo = Utils.GenerateWRPCToken(urlPath, user, tokenKey);

                headerItem = new WebTestRequestHeader();
                headerItem.Name = "crmwrpctokentimestamp";
                headerItem.Value = rpcInfo.timeStamp.ToString();
                wtr.Headers.Add(headerItem);
                headerItem = new WebTestRequestHeader();
                headerItem.Name = "crmwrpctoken";
                headerItem.Value = rpcInfo.token;
                wtr.Headers.Add(headerItem);
                wtr.Method = "Post";
            }
            yield return (wtr);

            af = new AdvancedFind.AdvancedFind();
            wtr = null;

            try { af.GetEntityFieldList("reportvisibility"); }
            catch (crmException x)
            {
                wtr = (CrmRequest)x.wtr;
                wtr.Url = Utils.ReplaceServerName(wtr.Url, user);

                string urlPath = wtr.Url.Remove(0, crmServer.Length);
                urlPath = urlPath.Remove(0, user["organizationName"].Length + 1);

                rpcInfo = Utils.GenerateWRPCToken(urlPath, user, tokenKey);

                headerItem = new WebTestRequestHeader();
                headerItem.Name = "crmwrpctokentimestamp";
                headerItem.Value = rpcInfo.timeStamp.ToString();
                wtr.Headers.Add(headerItem);
                headerItem = new WebTestRequestHeader();
                headerItem.Name = "crmwrpctoken";
                headerItem.Value = rpcInfo.token;
                wtr.Headers.Add(headerItem);
                wtr.Method = "Post";
            }
            yield return (wtr);

            try { af.GetLinkedEntityList("reportvisibility"); }
            catch (crmException x)
            {
                wtr = (CrmRequest)x.wtr;
                wtr.Url = Utils.ReplaceServerName(wtr.Url, user);

                string urlPath = wtr.Url.Remove(0, crmServer.Length);
                urlPath = urlPath.Remove(0, user["organizationName"].Length + 1);

                rpcInfo = Utils.GenerateWRPCToken(urlPath, user, tokenKey);

                headerItem = new WebTestRequestHeader();
                headerItem.Name = "crmwrpctokentimestamp";
                headerItem.Value = rpcInfo.timeStamp.ToString();
                wtr.Headers.Add(headerItem);
                headerItem = new WebTestRequestHeader();
                headerItem.Name = "crmwrpctoken";
                headerItem.Value = rpcInfo.token;
                wtr.Headers.Add(headerItem);
                wtr.Method = "Post";
            }
            yield return (wtr);

            try { af.GetQueryList("contract", 0, true, true, false); }
            catch (crmException x)
            {
                wtr = (CrmRequest)x.wtr;
                wtr.Url = Utils.ReplaceServerName(wtr.Url, user);

                string urlPath = wtr.Url.Remove(0, crmServer.Length);
                urlPath = urlPath.Remove(0, user["organizationName"].Length + 1);

                rpcInfo = Utils.GenerateWRPCToken(urlPath, user, tokenKey);

                headerItem = new WebTestRequestHeader();
                headerItem.Name = "crmwrpctokentimestamp";
                headerItem.Value = rpcInfo.timeStamp.ToString();
                wtr.Headers.Add(headerItem);
                headerItem = new WebTestRequestHeader();
                headerItem.Name = "crmwrpctoken";
                headerItem.Value = rpcInfo.token;
                wtr.Headers.Add(headerItem);
                wtr.Method = "Post";
            }
            yield return (wtr);

            try { af.GetSystemQuery("{00000000-0000-0000-00AA-000000666500}"); }
            catch (crmException x)
            {
                wtr = (CrmRequest)x.wtr;
                wtr.Url = Utils.ReplaceServerName(wtr.Url, user);

                string urlPath = wtr.Url.Remove(0, crmServer.Length);
                urlPath = urlPath.Remove(0, user["organizationName"].Length + 1);

                rpcInfo = Utils.GenerateWRPCToken(urlPath, user, tokenKey);

                headerItem = new WebTestRequestHeader();
                headerItem.Name = "crmwrpctokentimestamp";
                headerItem.Value = rpcInfo.timeStamp.ToString();
                wtr.Headers.Add(headerItem);
                headerItem = new WebTestRequestHeader();
                headerItem.Name = "crmwrpctoken";
                headerItem.Value = rpcInfo.token;
                wtr.Headers.Add(headerItem);
                wtr.Method = "Post";
            }
            yield return (wtr);

            try { af.GetDefaultAdvancedFindView("contract", false); }
            catch (crmException x)
            {
                wtr = (CrmRequest)x.wtr;
                wtr.Url = Utils.ReplaceServerName(wtr.Url, user);

                string urlPath = wtr.Url.Remove(0, crmServer.Length);
                urlPath = urlPath.Remove(0, user["organizationName"].Length + 1);

                rpcInfo = Utils.GenerateWRPCToken(urlPath, user, tokenKey);

                headerItem = new WebTestRequestHeader();
                headerItem.Name = "crmwrpctokentimestamp";
                headerItem.Value = rpcInfo.timeStamp.ToString();
                wtr.Headers.Add(headerItem);
                headerItem = new WebTestRequestHeader();
                headerItem.Name = "crmwrpctoken";
                headerItem.Value = rpcInfo.token;
                wtr.Headers.Add(headerItem);
                wtr.Method = "Post";
            }
            yield return (wtr);

            try { af.GetEntityFieldList("contract"); }
            catch (crmException x)
            {
                wtr = (CrmRequest)x.wtr;
                wtr.Url = Utils.ReplaceServerName(wtr.Url, user);

                string urlPath = wtr.Url.Remove(0, crmServer.Length);
                urlPath = urlPath.Remove(0, user["organizationName"].Length + 1);

                rpcInfo = Utils.GenerateWRPCToken(urlPath, user, tokenKey);

                headerItem = new WebTestRequestHeader();
                headerItem.Name = "crmwrpctokentimestamp";
                headerItem.Value = rpcInfo.timeStamp.ToString();
                wtr.Headers.Add(headerItem);
                headerItem = new WebTestRequestHeader();
                headerItem.Name = "crmwrpctoken";
                headerItem.Value = rpcInfo.token;
                wtr.Headers.Add(headerItem);
                wtr.Method = "Post";
            }
            yield return (wtr);

            try { af.GetLinkedEntityList("contract"); }
            catch (crmException x)
            {
                wtr = (CrmRequest)x.wtr;
                wtr.Url = Utils.ReplaceServerName(wtr.Url, user);

                string urlPath = wtr.Url.Remove(0, crmServer.Length);
                urlPath = urlPath.Remove(0, user["organizationName"].Length + 1);

                rpcInfo = Utils.GenerateWRPCToken(urlPath, user, tokenKey);

                headerItem = new WebTestRequestHeader();
                headerItem.Name = "crmwrpctokentimestamp";
                headerItem.Value = rpcInfo.timeStamp.ToString();
                wtr.Headers.Add(headerItem);
                headerItem = new WebTestRequestHeader();
                headerItem.Name = "crmwrpctoken";
                headerItem.Value = rpcInfo.token;
                wtr.Headers.Add(headerItem);
                wtr.Method = "Post";
            }
            yield return (wtr);

            AdvancedFind_fetchData_aspx fetchData_aspx = new AdvancedFind_fetchData_aspx(user);

            fetchData_aspx.FetchXml = fetchXml;
            fetchData_aspx.LayoutXml = layoutXml;
            fetchData_aspx.EntityName = entityName;
            fetchData_aspx.ViewId = viewId;
            fetchData_aspx.DefaultAdvFindViewId = viewId;
            fetchData_aspx.ViewType = viewType;
            fetchData_aspx.SortCol = sortCol;
            fetchData_aspx.SortDescend = sortDescend;

            fetchData_aspx.QueryId = new Guid("{687635FF-5117-40C8-9A04-3467307134E1}");
            fetchData_aspx.EntityCode = 9100;

            yield return (fetchData_aspx);

            this.EndTransaction("AdvancedFindContract");
        }

        public string fetchXml = @"<fetch version=""1.0"" output-format=""xml-platform"" mapping=""logical"" distinct=""false""><entity name=""contract""><attribute name=""title""/><attribute name=""contractid""/><order attribute=""title"" descending=""false""/><filter type=""and""><condition attribute=""title"" operator=""like"" value=""&#x25;" + Utils.GetRandomString(4, 4) + @"&#x25;""/></filter></entity></fetch>";
        public string layoutXml = @"<grid name=""resultset"" object=""1010"" jump=""title"" select=""1"" icon=""1"" preview=""1""><row name=""result"" id=""contractid""><cell name=""title"" width=""300"" /></row></grid>";
        public string entityName = "contract";
        public Guid viewId = new Guid("{00000000-0000-0000-00AA-000000666500}");
        public int viewType = 1039;
        public string sortCol = "title";
        public bool sortDescend = false;

        private WebTestRequestHeader headerItem;
        private WRPCInfo rpcInfo;

        private CRMEntity user;
        private string crmServer;
        private string tokenKey;
    }
}